package cn.wolfcode.service.impl;

import cn.wolfcode.domain.Destination;
import cn.wolfcode.domain.Travel;
import cn.wolfcode.domain.UserInfo;
import cn.wolfcode.exception.LogicException;
import cn.wolfcode.query.QueryObject;
import cn.wolfcode.query.TravelQueryObject;
import cn.wolfcode.redis.IUserInfoRedisService;
import cn.wolfcode.repsitory.TravelRepsitory;
import cn.wolfcode.service.*;
import cn.wolfcode.util.JsonResult;
import cn.wolfcode.vo.TravelCondition;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * @Description: 旅游业务逻辑实现类
 * @Author: 伍家钰
 * @Date: 2020/8/7 16:20
 * @Version: 1.0
 */
@Service
public class TravelServiceImpl implements ITravelService {
    @Resource
    private TravelRepsitory travelRepsitory;
    @Resource
    private MongoTemplate mongoTemplate;
    @Resource
    private IUserInfoService userInfoService;
    @Resource
    private IDestinationService destinationService;
    @Resource
    private IUserInfoRedisService userInfoRedisService;

    @Override
    public void save(Travel travel) {
        travelRepsitory.save(travel);
    }

    @Override
    public void delete(String id) {
        travelRepsitory.deleteById(id);
    }

    @Override
    public void update(Travel travel) {
        travelRepsitory.save(travel);
    }

    @Override
    public Travel get(String id) {
        Optional<Travel> optional = travelRepsitory.findById(id);
        if (optional.isPresent()) {
            Travel travel = optional.get();
            String userId = travel.getUserId();
            UserInfo userInfo = userInfoService.get(userId);
            // 设置地点(前端有个坑)href="'/views/destination/guide?id='+detail.dest.id"
            travel.setDest(destinationService.get(travel.getDestId()));
            travel.setAuthor(userInfo);
            return travel;
        }
        return null;
    }

    @Override
    public List<Travel> list() {
        return travelRepsitory.findAll();
    }

    @Override
    public Page<Travel> query(TravelQueryObject qo) {
        Query query = new Query();
        Pageable pageable = null;
        //判断qo中state的状态值是否大于0是则执行的是后端游记管理的高级查询
        if (qo.getState() > 0) {
            query.addCriteria(Criteria.where("state").is(qo.getState()));
            pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.ASC, "_id");
            query.with(pageable);
        } else {

            /*
             * 查询指定目的地的游记
             */
            if (StringUtils.hasText(qo.getDestId())) {
                query.addCriteria(Criteria.where("destId").is(qo.getDestId()));
            }

            // 判断是否添加指定天数范围查询游记的条件
            TravelCondition day = qo.getDay();
            if (day != null) {
                query.addCriteria(Criteria.where("day").gte(day.getMin()).lte(day.getMax()));
            }

            // 判断是否加指定花费的高查条件
            TravelCondition perExpendType = qo.getPerExpendType();
            if (perExpendType != null) {
                query.addCriteria(Criteria.where("perExpend").gte(perExpendType.getMin()).lte(perExpendType.getMax()));
            }

            // 判断是否是热门查询还是最新查询
            String orderType = qo.getOrderType();
            if (StringUtils.hasText(orderType)) {
                // 当前页显示的数据,Pageable是PageRequest的父接口的父接口
                pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.DESC,
                        orderType);
                query.with(pageable);
            }
        }
        // 总数据
        long total = mongoTemplate.count(query, Travel.class);
        if (total == 0) {
            // 如果返回null会报错
            return Page.empty();
        }

        // 遍历添加作者
        List<Travel> list = mongoTemplate.find(query, Travel.class);
        // 遍历游记集合拿到集合userId
        for (Travel travel : list) {
            String userId = travel.getUserId();
            // 获取作者
            UserInfo userInfo = userInfoService.get(userId);
            // 将作名设置进游记对象中
            travel.setAuthor(userInfo);
        }
        return new PageImpl<>(list, pageable, total);
    }

    @Override
    public Object audit(String id, int state) {
        // 1.先判断游记是否存在
        Travel travel = this.get(id);
        if (travel != null) {
            // 2.判断游记是否为空,是否待审,不为空并且待审则进入审核阶段
            if (travel.getState() == Travel.STATE_WAITING) {
                // 审核通过修改状态
                travel.setState(state);
                // 3.修改审核状态,修改成发布状态
                travel.setIsPublic(Travel.ISPUBLIC_YES);
                // 4.设置发布时间
                travel.setCreateTime(new Date());
                // 5.记录最新更新时间
                travel.setLastUpdateTime(new Date());
                this.update(travel);
                // 操作成功
                return JsonResult.success();
            } else {
                // 审核拒绝
                // 6.修改审核状态
                travel.setIsPublic(Travel.ISPUBLIC_NO);
                // 7.发布时间设为null
                travel.setCreateTime(null);
                // 8.记录最新更新时间
                travel.setLastUpdateTime(new Date());
                this.update(travel);
                // 操作成功
                return JsonResult.success();
            }
        }
        return new JsonResult<>(JsonResult.CODE_NOLOGIN, "稿件不存在", null);
    }

    @Override
    public String getContentById(String id) {
        Travel travel = this.get(id);
        String content = travel.getContent();
        return content;
    }

    @Override
    public Object updateState(String id, int state) {
        // 根据id获取对象
        Travel travel = this.get(id);
        // 判断对象是否为空
        // 判断是否为发布状态
        if (travel != null && travel.getState() == Travel.STATE_RELEASE) {
            // 修改对象的状态为下架状态
            travel.setState(state);
            // 修改对象的发布时间为null
            travel.setReleaseTime(null);
            // 设置最新修改时间
            travel.setLastUpdateTime(new Date());
            this.update(travel);
            return JsonResult.success();
        }
        throw new LogicException("下架失败,只有发布的游记才能下架!");
    }

    @Override
    public void saveOrUpdate(Travel travel, HttpServletRequest request) {
        // 判断是否有id
        if (StringUtils.hasText(travel.getId())) {
            // 编辑

        } else {
            // 保存(首先维护冗余字段)
            // 区域名称
            Destination destination = destinationService.get(travel.getDestId());
            travel.setDestName(destination.getName());
            // 用户id
            String token = request.getHeader("token");
            UserInfo userInfo = userInfoRedisService.getByToken(token);
            travel.setUserId(userInfo.getId());
            // 创建时间
            travel.setCreateTime(new Date());
            // 最后修改时间
            travel.setLastUpdateTime(new Date());
            this.save(travel);
        }

    }

    @Override
    public List<Travel> queryViewnumTop3(String destId) {
        Pageable pageable = PageRequest.of(0, 3, Sort.Direction.DESC, "viewnum");
        return travelRepsitory.findByDestId(destId, pageable);
    }
}
